package com.cloud.lan.config.redis;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.Duration;

/**
 * redis 多实例
 * @author ErKang
 * @date Created in 2022/4/23 17:22
 * @title RedisConfig.java
 * Department: Product development
 */
@Configuration
public class RedisConfig {

    //通用连接地址
    // DB0
    @Value("${redis0.host}")
    private String host0;
    @Value("${redis0.port}")
    private int port0;
    @Value("${redis0.password}")
    private String password0;
    //这里默认放DB1
    @Value("${redis0.database.db:1}")
    private int redis0Db1;
    // 连接超时时长（毫秒）
    @Value("${redis0.timeout:6000}")
    private int timeout;
    // 连接池最大连接数（使用负值表示没有限制）
    @Value("${redis0.pool.max-active:100}")
    private int maxActive;
    // 连接池中的最大空闲连接
    @Value("${redis0.pool.max-idle:3}")
    private int maxIdle;
    // 连接池中的最小空闲连接
    @Value("${redis0.pool.min-idle:0}")
    private int minIdle;
    // 连接池最大阻塞等待时间（使用负值表示没有限制）
    @Value("${redis0.pool.max-wait:-1}")
    private int maxWait;


    // DB1
    @Value("${redis1.host}")
    private String host1;
    @Value("${redis1.port}")
    private int port1;
    @Value("${redis1.password}")
    private String password1;
    // 这里默认放DB3
    @Value("${redis1.database.db:3}")
    private int redis1Db3;

    @Bean
    public GenericObjectPoolConfig getPoolConfig() {
        // 配置redis连接池
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWait);
        return poolConfig;
    }

    @Primary
    @Bean(name = "redisTemplate0")
    public StringRedisTemplate getRedisTemplate0() {
        return getStringRedisTemplate(host0, port0, password0, redis0Db1);
    }

    /**
     * 第二数据源 共通数据源
     * @author ErKang
     * @return org.springframework.data.redis.core.StringRedisTemplate
     * 2022/4/23 17:25
     */
    @Bean(name = "commonRedis")
    public StringRedisTemplate commonRedis() {
        return getStringRedisTemplate(host1, port1, password1, redis1Db3);
    }

    private StringRedisTemplate getStringRedisTemplate(String host, int port, String password, int database) {
        // 构建工厂对象
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(host);
        config.setPort(port);
        config.setPassword(RedisPassword.of(password));
        LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofSeconds(timeout))
                .poolConfig(getPoolConfig())
                .build();
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config, clientConfig);
        // 设置使用的redis数据库
        factory.setDatabase(database);
        // 重新初始化工厂
        factory.afterPropertiesSet();
        return new StringRedisTemplate(factory);
    }
}
